/* SPDX-License-Identifier: BSD-2-Clause */

/* GR1553B BC driver
 *
 * COPYRIGHT (c) 2010.
 * Cobham Gaisler AB.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * OVERVIEW
 * ========
 * This driver controls the BC device, located at an on-chip AMBA or an
 * AMBA-over-PCI bus. The driver operates the BC device and provides you
 * with interrupt services and core control. The driver start execution of
 * a synchronuos and/or an asynchronous BC descriptor List. The list contains
 * a descriptor table and a software description to make some operations
 * possible, for example translate descriptor-address into descriptor-number.
 *
 * BC descriptors are generated by the list API, available in gr1553bc_list.h.
 *
 * See gr1553bc_list.h for more information.
 */

#ifndef __GR1553BC_H__
#define __GR1553BC_H__

#ifdef __cplusplus
extern "C" {
#endif

/* Forward declaration */
struct gr1553bc_list;
struct gr1553bc_major;
struct gr1553bc_minor;
struct gr1553bc_minor_cfg;
struct gr1553bc_major_cfg;

#ifdef __cplusplus
}
#endif

#include <stdint.h>
#include "gr1553bc_list.h"

#ifdef __cplusplus
extern "C" {
#endif

/* Register GR1553B driver needed by BC driver */
extern void gr1553bc_register(void);

/* A BC descriptor accessed as is */
struct gr1553bc_bd_raw {
	volatile uint32_t words[4];
};

/* A BC descriptor accessed as a transfer descriptor */
struct gr1553bc_bd_tr {
	volatile uint32_t settings[2];
	volatile uint32_t dptr;
	volatile uint32_t status;
};

/* A BC descriptor accessed as a conditional descriptor */
struct gr1553bc_bd_cond {
	volatile uint32_t cond;
	volatile uint32_t bdptr;
	volatile uint32_t padding[2];
};

/* A BC descriptor accessed any way */
union gr1553bc_bd {
	struct gr1553bc_bd_raw raw;
	struct gr1553bc_bd_tr tr;
	struct gr1553bc_bd_cond cond;
};

/* Current state of the BC hardware */
struct gr1553bc_status {
	unsigned int status;
	unsigned int time;
};

#define KEEP_TIMESLOT 0x10
/* Initialize a BC descriptor. The words written is controllable by
 * the flags argument.
 * 
 * flags:
 *  bit[N=0..3]: 1 = set BD wordN according to argument wordN,
 *               0 = do not modify BD wordN
 *
 *  If bit KEEP_TIMESLOT is set the time slot of word0 is preserved,
 *  this bit only have an affect when the descriptor is a transfer
 *  descriptor.
 */
extern void gr1553bc_bd_init(
	union gr1553bc_bd *bd,
	unsigned int flags,
	uint32_t word0,
	uint32_t word1,
	uint32_t word2,
	uint32_t word3
	);

/* Initialize a Transfer descriptor
 *
 * Arguments:
 *	struct gr1553bc_bd_tr *bd
 * 	uint32_t setting0
 *	uint32_t setting1
 *	uint32_t data
 *	uint32_t status
 */
#define gr1553bc_bd_tr_init(bd, set0, set1, data, status) \
		gr1553bc_bd_init((union gr1553bc_bd *)bd,\
					0xf, set0, set1, data, status)
/* Initializa a Condition descriptor
 *
 * Arguments:
 *	struct gr1553bc_bd_cond *bd
 * 	uint32_t cond
 *	uint32_t jump_adr
 */
#define gr1553bc_bd_cond_init(bd, cond, jump_adr) \
		gr1553bc_bd_init((union gr1553bc_bd *)bd, \
					0xf, cond, jump_adr, 0, 0)

/* Size of a descriptor */
#define GR1553BC_BD_SIZE sizeof(struct gr1553bc_bd_raw)

/* Alignment of a descriptor */
#define GR1553BC_BD_ALIGN 16

/* End of list marker */
#define GR1553BC_TR_EOL 0x80ffffff

#define GR1553BC_BD_TYPE	0x80000000

/* Condition descriptor bits */
#define GR1553BC_UNCOND_JMP	0x820000ff
#define GR1553BC_UNCOND_IRQ	0x860000ff
#define GR1553BC_UNCOND_NOJMP	0x82000000

/* Transfer descriptor bits */
#define GR1553BC_TR_DUMMY_0	0x00000000
#define GR1553BC_TR_DUMMY_1	0x80000000

#define GR1553BC_TR_TIME	0x0000ffff

#define GR1553BC_TR_EXTTRIG	0x40000000

/* Take a GR1553BC hardware device identified by instance index (minor).
 * A pointer is returned that is used internally by the GR1553BC
 * driver, it is used as an input paramter 'bc' to all other
 * functions that manipulate the hardware.
 */
extern void *gr1553bc_open(int minor);

extern void gr1553bc_close(void *bc);

/* Stores Current Major/Minor frame number and the Slot number executing
 * into the location indicated by 'mid'. There may be two lists executing
 * in "parallel", the 'async' argument select for which list the MID is 
 * looked up, the Syncronous (async=0) list or the Asynchronous (async=1) 
 * list.
 *
 */
extern int gr1553bc_indication(void *bc, int async, int *mid);

/* Trigger external time sync by writing to the BC action register.
 * This may be good for debugging or if the time management is 
 * implemented in software.
 *
 * if trig=0 the external trigger memory is cleared.
 * if trig!=0 the external trigger memory is set.
 */
extern void gr1553bc_ext_trig(void *bc, int trig);

/* Configure the GR1553BC driver */
/*extern int gr1553bc_config(struct gr1553bc_config *cfg);*/

/* Start major frame processing. At least one list pointer must be 
 * non-zero to affect BC operation. The BC communication is enabled
 * depending on list and Interrupts are enabled. This function can
 * be called multiple times.
 *
 * If a list is already executing it will be replaced with the new
 * list.
 *
 * list        - Schedule Transfer List
 * list_async  - Asynchronous list
 */
extern int gr1553bc_start
	(
	void *bc,
	struct gr1553bc_list *list,
	struct gr1553bc_list *list_async
	);

/* Pause GR1553B BC scheduled transfers.
 *
 * Does not affect asynchronous operation.
 */
extern int gr1553bc_pause(void *bc);

/* Restart GR1553B BC scheduled transfers, after being paused 
 *
 * Does not affect asynchronous operation.
 */
extern int gr1553bc_restart(void *bc);

/* Stop BC transmission.
 *
 * OPTIONS
 *   bit0 - 1=STOP schedule list
 *   bit1 - 1=STOP asynchronous list
 */
extern int gr1553bc_stop(void *bc, int options);

/* Standard IRQ function setup. IRQ can be generated by condition descriptors
 * or by transfer descriptors or by errors.
 *
 * Condition descriptors are inserted into the list by user, each condition
 * may have a custom function and data assigned to it, see 
 * gr1553bc_slot_irq_prepare(). IRQs generated by condition descriptors are
 * not handled by this function.
 *
 * Transfer descriptors can generate IRQ if enabled by user.
 *
 * IRQs generated by transfer descriptors or by BC errors (DMA error etc.)
 * is handled by this standard ISR handler.
 */
extern int gr1553bc_irq_setup
	(
	void *bc,
	bcirq_func_t func,
	void *data
	);

/* Get Current BC hardware state/status. The Status is stored into the
 * area pointed to by status. See "struct gr1553bc_status" for more
 * info.
 */
extern void gr1553bc_status(void *bc, struct gr1553bc_status *status);

#ifdef __cplusplus
}
#endif

#endif /* __GR1553BC_H__ */
